/**
 * @file      icm20948_dmp_driver.h
 * @brief     ICM20948 DMP驱动接口头文件
 * @version   1.0
 * @date      2023-07-15
 * @note      基于TDK/InvenSense官方eMD-SmartMotion库
 */

#ifndef ICM20948_DMP_DRIVER_H
#define ICM20948_DMP_DRIVER_H

#include <stdint.h>
#include <stdbool.h>

// DMP支持的功能枚举类型
typedef enum {
    ICM20948_DMP_FEATURE_NONE       = 0,
    ICM20948_DMP_FEATURE_6X_QUAT    = (1 << 0),   // 6轴四元数（陀螺仪+加速度计）
    ICM20948_DMP_FEATURE_9X_QUAT    = (1 << 1),   // 9轴四元数（陀螺仪+加速度计+磁力计）
    ICM20948_DMP_FEATURE_PEDOMETER  = (1 << 2),   // 计步器
    ICM20948_DMP_FEATURE_GYRO_CAL   = (1 << 3),   // 陀螺仪校准
    ICM20948_DMP_FEATURE_FLIP_PICKUP= (1 << 4),   // 翻转/拾取检测
    ICM20948_DMP_FEATURE_TAP        = (1 << 5),   // 轻敲检测
    ICM20948_DMP_FEATURE_BAT_TAP    = (1 << 6),   // 双击检测
    ICM20948_DMP_FEATURE_ORIENT     = (1 << 7)    // 屏幕方向检测
} ICM20948_DMP_Feature_t;

// DMP四元数数据结构体
typedef struct {
    int32_t q1;    // w分量
    int32_t q2;    // x分量
    int32_t q3;    // y分量
    int32_t q4;    // z分量
    uint32_t accuracy; // 精度
    uint32_t timestamp; // 时间戳
} ICM20948_DMP_Quaternion_t;

// DMP计步器数据结构体
typedef struct {
    uint32_t steps;       // 步数
    uint32_t timestamp;   // 时间戳
} ICM20948_DMP_Pedometer_t;

// DMP姿态欧拉角数据结构体
typedef struct {
    float roll;     // 横滚角（绕X轴）
    float pitch;    // 俯仰角（绕Y轴）
    float yaw;      // 偏航角（绕Z轴）
    uint32_t accuracy;  // 精度
    uint32_t timestamp; // 时间戳
} ICM20948_DMP_EulerAngles_t;

/**
 * @brief 初始化ICM20948 DMP功能
 * @param features 需要启用的DMP特性（可以用按位或组合多个特性）
 * @return 0: 成功, 非0: 错误代码
 */
int8_t ICM20948_DMP_Init(uint16_t features);

/**
 * @brief 加载DMP固件到ICM20948
 * @return 0: 成功, 非0: 错误代码
 */
int8_t ICM20948_DMP_LoadFirmware(void);

/**
 * @brief 启用/禁用DMP功能
 * @param enable true: 启用, false: 禁用
 * @return 0: 成功, 非0: 错误代码
 */
int8_t ICM20948_DMP_Enable(bool enable);

/**
 * @brief 重置DMP
 * @return 0: 成功, 非0: 错误代码
 */
int8_t ICM20948_DMP_Reset(void);

/**
 * @brief 从DMP FIFO读取原始四元数数据
 * @param quat 四元数数据结构体指针
 * @return 0: 成功, 非0: 错误代码或无数据
 */
int8_t ICM20948_DMP_ReadQuaternion(ICM20948_DMP_Quaternion_t *quat);

/**
 * @brief 从DMP FIFO读取欧拉角数据
 * 注：此函数会先读取四元数，再转换为欧拉角
 * @param angles 欧拉角数据结构体指针
 * @return 0: 成功, 非0: 错误代码或无数据
 */
int8_t ICM20948_DMP_ReadEulerAngles(ICM20948_DMP_EulerAngles_t *angles);

/**
 * @brief 从DMP读取计步数据
 * @param pedometer 计步器数据结构体指针
 * @return 0: 成功, 非0: 错误代码或无数据
 */
int8_t ICM20948_DMP_ReadPedometerData(ICM20948_DMP_Pedometer_t *pedometer);

/**
 * @brief 设置DMP传感器采样率
 * @param accel_rate 加速度计采样率 (Hz)
 * @param gyro_rate 陀螺仪采样率 (Hz)
 * @return 0: 成功, 非0: 错误代码
 */
int8_t ICM20948_DMP_SetSensorRate(uint16_t accel_rate, uint16_t gyro_rate);

/**
 * @brief 设置DMP FIFO传输速率
 * @param rate 以Hz表示的速率
 * @return 0: 成功, 非0: 错误代码
 */
int8_t ICM20948_DMP_SetFifoRate(uint16_t rate);

/**
 * @brief 检查DMP FIFO是否有可用数据
 * @return true: 有可用数据, false: 无可用数据
 */
bool ICM20948_DMP_DataReady(void);

/**
 * @brief DMP中断处理函数
 * 在ICM20948的中断处理函数中调用此函数
 */
void ICM20948_DMP_InterruptHandler(void);

/**
 * @brief 将四元数转换为欧拉角
 * @param quat 四元数结构体指针
 * @param angles 欧拉角结构体指针
 */
void ICM20948_DMP_QuaternionToEuler(const ICM20948_DMP_Quaternion_t *quat, ICM20948_DMP_EulerAngles_t *angles);

/**
 * @brief 校准DMP
 * @return 0: 成功, 非0: 错误代码
 * @note 设备需要保持静止来完成校准
 */
int8_t ICM20948_DMP_Calibrate(void);

#endif /* ICM20948_DMP_DRIVER_H */ 